<script lang="ts" setup>
import { useCommon } from '~/store/common'
import type { InputValidate } from '~/types'
import { objToMd5 } from '~/utils/helper'

// 弹窗类型
type TypeDialog = 'login' | 'register' | 'findPsd'

// 表单类型
interface UserFromType {
  userName: string
  password: string
  rePassword: string
  phone: string
  phoneCode: string
}
const title = import.meta.env.VITE_APP_TITLE
const { $message } = useNuxtApp()
const userStore = useUser()
const commonStore = useCommon()
// 弹窗显示
const loginVisible = ref<boolean>(false)
// 弹窗类型
const dialogType = ref<TypeDialog>('login')
// 登录按钮加载
const loginBtnLoading = ref<boolean>(false)
// 注册按钮加载
const registerBtnLoading = ref<boolean>(false)
// 登录注册切换
const loginTypeList = ref<object>({
  login: '登录',
  register: '注册'
})
// 提交表单数据
const userFrom = ref<UserFromType>({
  userName: '',
  password: '',
  rePassword: '',
  phone: '',
  phoneCode: ''
})
// 用户名校验
const vidUserName = ref<InputValidate[]>([
  {
    required: true,
    message: '请输入账号'
  },
  {
    message: '请输入6-11位，包含字母+数字',
    validator: (e: string) => {
      return useValidate().userName(e)
    }
  }
])
// 密码校验
const vidPsd = ref<InputValidate[]>([
  {
    required: true,
    message: '请输入密码'
  },
  {
    message: '请输入8-12位，包含字母+数字',
    validator: (e: string) => {
      return useValidate().psd(e)
    }
  }
])
// 再次输入密码校验
const reVidPsd = ref<InputValidate[]>([
  {
    required: true,
    message: '请确认密码'
  },
  {
    message: '输入的密码不一致',
    validator: (e: string) => {
      return e === userFrom.value.password
    }
  }
])
// 验证手机号
const vidPhone = ref<InputValidate[]>([
  {
    required: true,
    message: '请输入手机号'
  },
  {
    message: '输入的手机号格式不正确',
    validator: (e: string) => {
      return useValidate().phone(e)
    }
  }
])
// 验证验证码
const vidPhoneCode = ref<InputValidate[]>([
  {
    required: true,
    message: '请输入验证码'
  },
  {
    message: '请输入正确的验证码',
    validator: (e: string) => {
      return useValidate().phoneCode(e)
    }
  }
])
// 倒计时
const timer = ref<any>(undefined)
// 60s
const seconds = ref<number>(60)
const secondLoading = ref<boolean>(false)
// 提交按钮状态
const submitBtnStatus = computed(() => {
  const flag
    = !!userFrom.value.userName
    && !!userFrom.value.password
    && useValidate().userName(userFrom.value.userName)
    && useValidate().psd(userFrom.value.password)

  if (dialogType.value === 'login') {
    return flag
  } else if (dialogType.value === 'register') {
    return flag && userFrom.value.rePassword === userFrom.value.password
  } else {
    return (
      !!userFrom.value.password
      && useValidate().psd(userFrom.value.password)
      && userFrom.value.rePassword === userFrom.value.password
      && !!userFrom.value.phone
      && !!userFrom.value.phoneCode
      && useValidate().phone(userFrom.value.phone)
      && useValidate().phoneCode(userFrom.value.phoneCode)
    )
  }
})

// 切换选择注册登录忘记密码类型
function selectLoginType(key: TypeDialog) {
  dialogType.value = key
  resetDialog()
}

// 重置事件
function resetDialog() {
  loginBtnLoading.value = false
  userFrom.value = {
    userName: '',
    password: '',
    rePassword: '',
    phone: '',
    phoneCode: ''
  }
  clearInterval(timer.value)
  timer.value = null
  seconds.value = 60
}

// 获取验证码
async function handleVerifyCode() {
  try {
    if (timer.value) {
      return
    }
    secondLoading.value = true
    await commonStore.handleCodePhone({
      userPhone: `+86-${userFrom.value.phone}`
    })

    // $message.success('获取验证码成功')
    secondLoading.value = false
    timer.value = setInterval(() => {
      seconds.value--
      if (seconds.value === 0) {
        clearInterval(timer.value)
        timer.value = null
        seconds.value = 60
      }
    }, 1000)
  } catch (e) {
    clearInterval(timer.value)
    timer.value = null
    seconds.value = 60
  } finally {
    secondLoading.value = false
  }
}

// 登录事件
async function handleLogin() {
  try {
    loginBtnLoading.value = true
    const params = {
      userName: userFrom.value.userName,
      password: objToMd5(userFrom.value.password)
    }
    await userStore.handleLogin(params)
    loginVisible.value = false
  } catch (e) {
    console.log(e)
  } finally {
    loginBtnLoading.value = false
  }
}

// 注册事件
async function handleRegister() {
  try {
    registerBtnLoading.value = true
    await userStore.handleRegister({
      userName: userFrom.value.userName,
      password: objToMd5(userFrom.value.password)
    })
    // $message.success('注册成功')
    loginVisible.value = false
  } catch (e) {
    console.error(e)
  } finally {
    registerBtnLoading.value = false
  }
}

// 找回账号
async function handleFindPsd() {
  try {
    loginBtnLoading.value = true
    await commonStore.handleFindPsd({
      password: objToMd5(userFrom.value.password),
      telPhone: `+86-${userFrom.value.phone}`,
      verifyCode: userFrom.value.phoneCode
    })
    // $message.success('修改密码成功')
    loginVisible.value = false
    resetDialog()
  } catch (e) {
    console.log(e)
  } finally {
    loginBtnLoading.value = false
  }
}

defineExpose({
  loginVisible
})
</script>

<template>
  <BaseDialog v-model="loginVisible" dialog-class="w-84 lg:w-120" @before-close="selectLoginType('login')">
    <!-- 登录注册弹窗 -->
    <div
      v-if="dialogType === 'login' || dialogType === 'register'"
      flex="~ col justify-between items-center"
      mxa
      mb-7.5
      mt-7.5
      w-66
      lg:w-90
    >
      <p mb-4 font-size-8 font-600>
        {{ title }}
      </p>
      <div flex="~ justify-items-start" mb-7.25 w-full border-rd-25 pxa font-size-4 bl-324065>
        <p
          v-for="(type, key) in loginTypeList"
          :key="key"
          :class="{ 'bg-324065': dialogType === key }"
          flex-1
          cursor-pointer
          border-rd-25
          py-1
          text-center
          @click="selectLoginType(key)"
        >
          {{ type }}
        </p>
      </div>
      <!-- 登录 -->
      <div v-if="dialogType === 'login'" w-full>
        <BaseInput
          v-model="userFrom.userName"
          :validate="vidUserName"
          input-class="mb-7.25"
          placeholder="账号(6-11位，字母+数字)"
        />
        <BaseInput
          v-model="userFrom.password"
          type="password"
          :validate="vidPsd"
          input-class="mb-7.25"
          placeholder="密码(8-12位，字母+数字)"
        />
        <p mb-6 text-center>
          <span>忘记密码？</span>
          <span cursor-pointer ct-F97316 @click="selectLoginType('findPsd')">找回密码</span>
        </p>
        <BaseButton
          :disabled="!submitBtnStatus"
          :loading="loginBtnLoading"
          round
          w-full
          text="登录"
          @click="handleLogin"
        />
      </div>
      <!-- 注册 -->
      <div v-if="dialogType === 'register'" w-full="">
        <BaseInput
          v-model="userFrom.userName"
          :validate="vidUserName"
          input-class="mb-7.25"
          placeholder="账号(6-11位，字母+数字)"
        />
        <BaseInput
          v-model="userFrom.password"
          type="password"
          :validate="vidPsd"
          input-class="mb-7.25"
          placeholder="密码(8-12位，字母+数字)"
        />
        <BaseInput
          v-model="userFrom.rePassword"
          type="password"
          :validate="reVidPsd"
          input-class="mb-7.25"
          placeholder="确认密码"
        />
        <p mb-6 text-center>
          <span>忘记密码？</span>
          <span cursor-pointer ct-f97316 @click="selectLoginType('findPsd')">找回密码</span>
        </p>
        <BaseButton
          :disabled="!submitBtnStatus"
          :loading="registerBtnLoading"
          round
          w-full
          text="注册"
          @click="handleRegister"
        />
      </div>
    </div>
    <!-- 找回密码弹窗 -->
    <div v-if="dialogType === 'findPsd'" flex="~ col justify-between items-center" mxa mb-7.5 mt-7.5 w-66 lg:w-90>
      <p mb-1 font-size-6 font-600>
        找回账号
      </p>
      <p mb-4 ct-ffffff80>
        找回账号仅支持绑定过手机号的账号
      </p>
      <BaseInput v-model="userFrom.phone" :validate="vidPhone" input-class="mb-7.25" placeholder="手机号" />
      <BaseInput v-model="userFrom.phoneCode" :validate="vidPhoneCode" input-class="mb-7.25" placeholder="验证码(6位)">
        <template #append>
          <div w-60 cursor-pointer border-rd-12 py-0.75 text-center bl-fd5b03 ct-fd5b03 @click="handleVerifyCode">
            <div v-if="secondLoading" i-ep:loading ma animate-spin text-2xl />
            <p v-else-if="timer">
              {{ `${seconds}s` }}
            </p>
            <p v-else>
              获取验证码
            </p>
          </div>
        </template>
      </BaseInput>
      <BaseInput
        v-model="userFrom.password"
        type="password"
        :validate="vidPsd"
        input-class="mb-7.25"
        placeholder="密码(8-12位，字母+数字)"
      />
      <BaseInput
        v-model="userFrom.rePassword"
        type="password"
        :validate="reVidPsd"
        input-class="mb-7.25"
        placeholder="确认密码"
      />
      <div flex="~ row gap5" w-full>
        <BaseButton flex-1 text="返回登录" type="info" lg:border-rd-22 @click="selectLoginType('login')" />
        <BaseButton
          :loading="loginBtnLoading"
          :disabled="!submitBtnStatus"
          flex-1
          lg:border-rd-22
          text="登录"
          @click="handleFindPsd"
        />
      </div>
    </div>
  </BaseDialog>
</template>
